package com.weijianhuawen.wjblog.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.weijianhuawen.wjblog.admin.mode.vo.tag.*;
import com.weijianhuawen.wjblog.admin.service.AdminTagService;
import com.weijianhuawen.wjblog.common.domain.dos.ArticleTagRelDo;
import com.weijianhuawen.wjblog.common.domain.dos.TagDo;
import com.weijianhuawen.wjblog.common.domain.mapper.ArticleTagRelMapper;
import com.weijianhuawen.wjblog.common.domain.mapper.TagMapper;
import com.weijianhuawen.wjblog.common.enums.ResponseCodeEnum;
import com.weijianhuawen.wjblog.common.exception.BizException;
import com.weijianhuawen.wjblog.common.model.vo.SelectRspVo;
import com.weijianhuawen.wjblog.common.utils.PageResponse;
import com.weijianhuawen.wjblog.common.utils.Response;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @version: java version 8
 * @Author: weijianhuawen
 * @description: 标签服务层， 其中ServiceImpl为mybatis plus 提供的一系列操作实现类 其中包含批量插入功能
 * @date: 2024-10-22 16:50
 */

@Service
@Slf4j
public class AdminTagServiecImpl extends ServiceImpl<TagMapper, TagDo> implements AdminTagService {
    @Resource
    private TagMapper tagMapper;
    @Resource
    private ArticleTagRelMapper articleTagRelMapper;

    @Override
    public Response addTag(AddTagReqVo vo) {
        //获取需要插入的集合
        List<TagDo> dos = vo.getTags()
                        .stream().map(tagName -> TagDo.builder()
                        .name(tagName.trim())
                        .createTime(LocalDateTime.now())
                        .updateTime(LocalDateTime.now())
                        .build())
                .collect(Collectors.toList());

        //批量插入
        try {
            saveBatch(dos);
        } catch (Exception e) {
            log.warn("传入标签集，含有重复标签，已忽略");
        }

        return Response.success();
    }

    @Override
    public Response findTagList(FindTagPageListReqVo findTagPageListReqVo) {
        //获取当前页，以及每一页需要展示的数量
        Long pageIndex = findTagPageListReqVo.getCurrent();
        Long size = findTagPageListReqVo.getSize();
        //开始时间
        LocalDate startDate = findTagPageListReqVo.getStartDate();
        //结束时间
        LocalDate endDate = findTagPageListReqVo.getEndDate();
        //查询标签名
        String tagName = findTagPageListReqVo.getTagName();
        //分页查询
        Page<TagDo> tagDoPage = tagMapper.selectPageList(pageIndex, size, tagName, startDate, endDate);
        List<TagDo> tagDos = tagDoPage.getRecords();

        //将do转为vo
        List<FindTagPageListRspVo> vos = null;
        if (!Collections.isEmpty(tagDos)) {
            vos = tagDos.stream()
                    .map(tagDo -> FindTagPageListRspVo.builder()
                            .id(tagDo.getId())
                            .tagName(tagDo.getName())
                            .createTime(tagDo.getCreateTime())
                            .articlesTotal(tagDo.getArticlesTotal())
                            .build())
                    .collect(Collectors.toList());
        }
        if (vos == null) vos = new ArrayList<>();
        return PageResponse.success(tagDoPage, vos);
    }

    @Override
    public Response deleteTag(DeleteTagReqVo vo) {
        //获取id
        Long id = vo.getId();
        //查询标签关联文章表，如果需删除标签存在文章关联，则不能删除
        ArticleTagRelDo articleTagRelDo = articleTagRelMapper.selectOneByTagId(id);

        if (Objects.nonNull(articleTagRelDo)) {
            // 存在关联无法删除
            log.warn("【标签管理服务】对应标签id:{}已被文章id:{}关联，无法删除！", articleTagRelDo.getTagId(), articleTagRelDo.getArticleId());
            throw new BizException(ResponseCodeEnum.TAG_BIND_ARTICLE);
        }
        int res = tagMapper.deleteById(id);
        return res == 1 ? Response.success() : Response.fail(ResponseCodeEnum.NOT_EXIST_TAG);
    }

    @Override
    public Response searchLikeTag(SearchLikeTagReqVo vo) {
        // 模糊查询
        //获取查询字段
        String key = vo.getKey();

        //查询
        List<TagDo> tagDos = tagMapper.searchLikeTag(key);

        //将do转换为vo
        List<SelectRspVo> vos = null;

        if (!Collections.isEmpty(tagDos)) {
            vos = tagDos.stream()
                    .map(tag -> SelectRspVo.builder()
                            .label(tag.getName())
                            .value(tag.getId())
                            .build())
                    .collect(Collectors.toList());
        }
        if (Objects.isNull(vos)) vos = new ArrayList<>();
        return Response.success(vos);
    }

    @Override
    public Response addOneCategory(AddOneTagReqVo vo) {
        //获取标签名
        String tagName = vo.getName();

        //判断标签名是否存在
        TagDo tagDo = tagMapper.selectByName(tagName);
        if (Objects.nonNull(tagDo)) {
            //已存在
            log.warn("标签名称： {}, 此标签已存在", tagDo.getName());
            throw new BizException(ResponseCodeEnum.TAG_NAME_IS_EXISTED);
        }
        tagDo = TagDo.builder().name(tagName.trim()).createTime(LocalDateTime.now()).updateTime(LocalDateTime.now()).build();
        tagMapper.insert(tagDo);
        return Response.success();
    }

    //查找所有标签列表，返回标签名与id
    @Override
    public Response findTagList() {
        //查询所有标签
        List<TagDo> tagDos = tagMapper.selectList(Wrappers.emptyWrapper());

        // 将do 转 vo
        List<SelectRspVo> vos = null;
        if (!CollectionUtils.isEmpty(tagDos)) {
            vos = tagDos.stream()
                    .map(tagDo -> {
                        return SelectRspVo.builder()
                        .value(tagDo.getId())
                        .label(tagDo.getName())
                        .build();
                    })
                    .collect(Collectors.toList());
        }
        if (vos == null) vos = Lists.newArrayList();
        return Response.success(vos);
    }
}
